package com.example.sdtreader;

import java.util.HashMap;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.text.TextUtils;
import android.util.Log;

public class UsbDeviceHelper {
    private static String TAG = "UsbDeviceHelper";
    private static UsbManager mUsbManager;
    private static UsbDevice mUsbDevice;

    private static UsbDeviceConnection mDeviceConnection;
    private static PendingIntent mPermissionIntent;
    private static Context mContext;

    private static String usbDevicePath = "";
    private static final String ACTION_USB_DEVICE_PERMISSION = "com.android.usb.USB_PERMISSION";
	/*
	UsbManager	获得 USB 管理器，与连接的 USB 设备通信。
	UsbDevice	USB 设备的抽象，每个UsbDevice 都代表一个 USB 设备。
	UsbInterface	定义了设备的功能集，一个 UsbDevice 可能包含一个或多个UsbInterface，每个 Interface 都是独立的。
	UsbEndpoint	UsbEndpoint 是 interface 的通信通道。
	UsbDeviceConnection	host 与 device 建立的连接，并在 endpoint 传输数据。
	UsbRequest	USB 请求包。
	UsbConstants	USB 常量的定义
	 */
    // 注1：UsbManager.ACTION_USB_DEVICE_ATTACHED对应的广播在USB每次插入时都能监听到，所以用这个就可以监听USB插入。
    // 注2：UsbManager.ACTION_USB_DEVICE_DETACHED用来监听USB拔出广播。
    /**
     * 注册USB设备插拔事件监听
     */
    public UsbDeviceHelper(Context context) {
        mContext = context;

        //发一个延时广播
        mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(
                "com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION"), PendingIntent.FLAG_IMMUTABLE); // Add FLAG_IMMUTABLE for Android S (API 31) and above

        // 注册USB设备权限管理广播
        IntentFilter filter = new IntentFilter("com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION");

        filter.addAction(ACTION_USB_DEVICE_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        mContext.registerReceiver(mUsbReceiver, filter);
    }

    public void unUsbDevPermission() {
        if (mContext != null)
            mContext.unregisterReceiver(mUsbReceiver);
    }

    // USB授权
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            if(intent == null)
                return;
            //设备插入，获取这个插入的UsbDevice
            UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            String action = intent.getAction();
            if (TextUtils.isEmpty(action))
                return;
            if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                // 设备插入，获取这个插入的UsbDevice
                // 向用户获取连接USB设备的授权
                Log.d(TAG, "UsbDevice (VID:" + usbDevice.getVendorId()
                        + ",PID:" + usbDevice.getProductId()
                        + ") DEVICE_ATTACHED");

                //requestUserPermission();

            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
                // 设备拔下，资源释放
                Log.d(TAG, "UsbDevice (VID:" + usbDevice.getVendorId()
                        + ",PID:" + usbDevice.getProductId()
                        + ") DEVICE_DETACHED");
            } else if (action.equals(ACTION_USB_DEVICE_PERMISSION) ||
                    action.equals("com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION")) {
                // 获取连接设备的权限
                boolean isGranted = intent.getBooleanExtra(
                        UsbManager.EXTRA_PERMISSION_GRANTED, false);
                if (isGranted) {
                    // 用户已授权
                } else {
                    // 用户未授权

                }
                Log.d(TAG, "permission device " + isGranted);
            }
        }
    };


    /**
     * 检测到设备插入之后，向用户请求连接设备的权限
     */
    private void requestUserPermission(UsbDevice usbDevice) {
    	//根据传入的NAME来取得对应的Object，然后转换成相应的服务对象
		//获取 UsbManager
    	mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        if (mUsbManager.hasPermission(usbDevice)){
            //已经有权限的话，直接初始化驱动
            //判断已经授予权限
            return;
        }
        //发一个延时广播(延迟执行的intent)
        PendingIntent mPendingIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent(ACTION_USB_DEVICE_PERMISSION), 0);
        //这一句会由系统弹出对话框，向用户获取连接授权
        mUsbManager.requestPermission(usbDevice, mPendingIntent);
    }

    public int getUsbFileDescriptor(int VendorId, int ProductID) {
        int UsbFileDescriptor = 0;
        mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        //获取设备连表
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        if (deviceList.size() <= 0) {
            return Common.ERR_No_DEVICE;
        }
        mUsbDevice = null;
        if (!deviceList.isEmpty()) {
            for (UsbDevice device : deviceList.values()) {
                usbDevicePath = device.getDeviceName();
                if ((device.getVendorId() == VendorId)
                        && (device.getProductId() == ProductID)) {
                    mUsbDevice = device;
                    // 判断下设备权限，如果没有权限，则请求权限
                    if (!mUsbManager.hasPermission(mUsbDevice)) {
                        mUsbManager.requestPermission(mUsbDevice,mPermissionIntent);
					}
					break;
                }
            }
        }
        if (mUsbDevice != null) {
            UsbDeviceConnection conn = null;
            if (mUsbManager.hasPermission(mUsbDevice)) {
                Log.d(TAG, "has permission");
                //打开设备
                conn = mUsbManager.openDevice(mUsbDevice);
            } else {
                Log.d(TAG, "no permission");
                return Common.ERR_No_PERMISSON;
            }

            if (conn == null) {
                return Common.ERR_OPEN;
            }
            mDeviceConnection = conn;

            //获取设备描述符
            UsbFileDescriptor = conn.getFileDescriptor();

            Log.d(TAG, " getFileDescriptor is " + UsbFileDescriptor);
            return UsbFileDescriptor;
        }
        return Common.ERR_No_DEVICE;
    }

    public String getUsbDevPath() {
        return usbDevicePath;
    }

    public boolean isOpen() {
        if ((mUsbManager != null) && (mUsbDevice != null) &&
                (mDeviceConnection != null)&& (mUsbManager.hasPermission(mUsbDevice))) {
            return true;
        }
        return false;
    }
}
